// WebRTC 管理类
class WebRTCManager {
  constructor() {
    // WebSocket 连接对象
    this.socket = null;
    // WebRTC 对等连接对象
    this.peerConnection = null;
    // 本地媒体流（摄像头/麦克风）
    this.localStream = null;
    // 远程媒体流（接收到的视频/音频）
    this.remoteStream = null;
    // 连接状态标志
    this.isConnected = false;
    // 当前直播间ID
    this.streamId = null;

    // WebRTC 配置
    this.config = {
      iceServers: [
        { urls: "stun:stun.l.google.com:19302" },
        { urls: "stun:stun1.l.google.com:19302" },
        // 多个免费的TURN服务器
        {
          urls: [
            "turn:openrelay.metered.ca:80",
            "turn:openrelay.metered.ca:443",
          ],
          username: "openrelayproject",
          credential: "openrelayproject",
        },
        {
          urls: "turn:relay.backups.cz",
          username: "webrtc",
          credential: "webrtc",
        },
        {
          urls: "turn:relay.backups.cz:3478",
          username: "webrtc",
          credential: "webrtc",
        },
      ],
      iceCandidatePoolSize: 10,
      // 强制使用统一模式
      bundlePolicy: "max-bundle",
      // ICE传输策略
      iceTransportPolicy: "all",
      // 启用旧版兼容性
      sdpSemantics: "unified-plan",
    };

    this.serverUrl = "ws://localhost:3003/ws";
  }

  async connect() {
    return new Promise((resolve, reject) => {
      try {
        // 创建 WebSocket 连接
        this.socket = new WebSocket(this.serverUrl);

        // 监听 WebSocket 连接成功事件
        this.socket.onopen = () => {
          console.log("WebSocket 连接成功");
          this.isConnected = true;
          this.setupSocketHandlers();
          resolve();
        };

        this.socket.onerror = (error) => {
          console.error("WebSocket 连接失败:", error);
          reject(new Error("无法连接到服务器"));
        };

        this.socket.onclose = () => {
          console.log("WebSocket 连接关闭");
          this.isConnected = false;
        };
      } catch (error) {
        reject(error);
      }
    });
  }

  setupSocketHandlers() {
    // 监听 WebSocket 消息事件
    this.socket.onmessage = async (event) => {
      try {
        const message = JSON.parse(event.data);
        await this.handleMessage(message);
      } catch (error) {
        console.error("处理消息失败:", error);
      }
    };
  }

  async handleMessage(message) {
    console.log("收到消息:", message);

    switch (message.type) {
      case "offer":
        await this.handleOffer(message);
        break;
      case "answer":
        await this.handleAnswer(message);
        break;
      case "ice-candidate":
        await this.handleIceCandidate(message);
        break;
      case "create-offer":
        await this.handleCreateOffer(message);
        break;
      case "stream-started":
        console.log("直播开始:", message.streamId);
        this.streamId = message.streamId;
        if (this.onStreamStarted) {
          this.onStreamStarted(message.streamId);
        }
        break;
      case "stream-stopped":
        console.log("直播结束");
        break;
      case "error":
        console.error("服务器错误:", message.error);
        if (this.onError) {
          this.onError(message.error);
        } else {
          alert("错误: " + message.error);
        }
        break;
      default:
        console.log("未知消息类型:", message.type);
    }
  }

  async startStreaming(stream) {
    this.localStream = stream;

    // 清理之前的连接
    if (this.peerConnection) {
      console.log("清理之前的PeerConnection");
      this.peerConnection.close();
      this.peerConnection = null;
    }

    // 重置候选队列
    this.pendingCandidates = [];

    // 创建新的 PeerConnection
    this.peerConnection = new RTCPeerConnection(this.config);
    console.log(
      "创建新的PeerConnection，初始状态:",
      this.peerConnection.signalingState
    );

    // 添加本地流
    console.log("=== 添加本地流到PeerConnection ===");
    console.log("本地流信息:");
    console.log("- 流ID:", stream.id);
    console.log("- 视频轨道数:", stream.getVideoTracks().length);
    console.log("- 音频轨道数:", stream.getAudioTracks().length);

    stream.getTracks().forEach((track, index) => {
      console.log(
        `📡 添加轨道${index}: kind=${track.kind}, enabled=${track.enabled}, readyState=${track.readyState}`
      );
      this.peerConnection.addTrack(track, stream);
    });

    // 验证发送器
    const senders = this.peerConnection.getSenders();
    console.log("📤 PeerConnection发送器数量:", senders.length);
    senders.forEach((sender, index) => {
      console.log(`发送器${index}:`, {
        track: sender.track?.kind,
        enabled: sender.track?.enabled,
        readyState: sender.track?.readyState,
      });
    });

    // 设置 ICE 候选事件
    this.peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        this.sendMessage({
          type: "ice-candidate",
          candidate: event.candidate,
        });
      }
    };

    // 通知服务器开始推流
    const streamId = this.generateStreamId();
    this.streamId = streamId; // 先保存streamId
    console.log("发送start-stream消息，streamId:", streamId);

    this.sendMessage({
      type: "start-stream",
      streamId: streamId,
    });

    // 备用方案：如果回调设置了，立即调用一次
    if (this.onStreamStarted) {
      console.log("立即调用onStreamStarted回调");
      this.onStreamStarted(streamId);
    }
  }

  async joinStream(streamId, videoElement) {
    this.streamId = streamId;
    this.remoteVideoElement = videoElement; // 保存视频元素引用

    // 清理之前的连接
    if (this.peerConnection) {
      console.log("清理之前的PeerConnection");
      this.peerConnection.close();
      this.peerConnection = null;
    }

    // 重置候选队列
    this.pendingCandidates = [];

    // 创建新的 PeerConnection
    this.peerConnection = new RTCPeerConnection(this.config);
    console.log(
      "创建新的PeerConnection，初始状态:",
      this.peerConnection.signalingState
    );

    // 处理远程流
    this.peerConnection.ontrack = (event) => {
      console.log("🎥 === 收到远程流事件 === 🎥");
      console.log("流数量:", event.streams.length);
      console.log("轨道数量:", event.track ? 1 : 0);
      console.log("轨道类型:", event.track?.kind);
      console.log("轨道状态:", event.track?.readyState);
      console.log("事件详情:", event);

      if (event.streams && event.streams[0]) {
        const stream = event.streams[0];
        console.log("远程流信息:");
        console.log("- 流ID:", stream.id);
        console.log("- 视频轨道数:", stream.getVideoTracks().length);
        console.log("- 音频轨道数:", stream.getAudioTracks().length);

        // 检查视频轨道状态
        stream.getVideoTracks().forEach((track, index) => {
          console.log(
            `- 视频轨道${index}: enabled=${track.enabled}, readyState=${track.readyState}`
          );
        });

        console.log("设置远程视频流到元素:", videoElement.id);

        // 先检查视频元素状态
        console.log("视频元素当前状态:");
        console.log("- paused:", videoElement.paused);
        console.log("- readyState:", videoElement.readyState);
        console.log("- networkState:", videoElement.networkState);
        console.log("- currentSrc:", videoElement.currentSrc);

        // 避免重复设置同一个流
        if (this.remoteStream && this.remoteStream.id === stream.id) {
          console.log("相同的流已存在，跳过重复设置");
          return;
        }

        // 停止之前的播放请求
        videoElement.pause();
        videoElement.srcObject = null;

        // 设置新的流
        videoElement.srcObject = stream;
        this.remoteStream = stream;

        console.log("srcObject设置完成，等待视频加载...");

        // 强制静音播放（确保能自动播放）
        videoElement.muted = true;

        // 等待流设置完成后再播放
        setTimeout(() => {
          console.log("🎬 开始尝试播放视频...");
          videoElement
            .play()
            .then(() => {
              console.log("✅ 视频播放成功！");
              // 触发流接收成功回调
              if (this.onStreamReceived) {
                this.onStreamReceived();
              }
            })
            .catch((error) => {
              console.error("❌ 视频播放失败:", error);
              console.log("🔧 视频播放失败，但流已接收，可能是自动播放限制");
              // 即使播放失败，也触发回调，因为流已经接收到了
              if (this.onStreamReceived) {
                this.onStreamReceived();
              }
            });
        }, 100);
      } else {
        console.warn("未收到有效的远程流");
      }
    };

    // 设置连接状态监听
    this.peerConnection.onconnectionstatechange = () => {
      console.log("连接状态:", this.peerConnection.connectionState);
      if (this.onConnectionStateChange) {
        this.onConnectionStateChange(this.peerConnection.connectionState);
      }
    };

    // 设置ICE连接状态监听
    this.peerConnection.oniceconnectionstatechange = () => {
      console.log("🧊 ICE连接状态:", this.peerConnection.iceConnectionState);

      switch (this.peerConnection.iceConnectionState) {
        case "checking":
          console.log("⏳ 正在检查ICE连接...");
          break;
        case "connected":
          console.log("✅ ICE连接成功！");
          // 当ICE连接成功时，强制尝试播放视频
          if (this.remoteVideoElement && this.remoteStream) {
            console.log("🎬 ICE连接成功，重新尝试播放视频");
            this.remoteVideoElement.play().catch((e) => {
              console.log("📺 自动播放被阻止，需要用户交互");
            });
          }
          break;
        case "completed":
          console.log("🎉 ICE连接完成！");
          break;
        case "failed":
          console.error("❌ ICE连接失败，可能需要TURN服务器");
          if (this.onError) {
            this.onError("网络连接失败，请检查网络设置");
          }
          break;
        case "disconnected":
          console.warn("⚠️ ICE连接断开");
          break;
        case "closed":
          console.log("🔒 ICE连接关闭");
          break;
      }
    };

    // 设置 ICE 候选事件
    this.peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        const candidate = event.candidate.candidate;
        const type = candidate.includes("typ host")
          ? "HOST"
          : candidate.includes("typ srflx")
          ? "SRFLX(STUN)"
          : candidate.includes("typ relay")
          ? "RELAY(TURN)"
          : "OTHER";

        console.log(`📡 发送ICE候选 [${type}]:`, candidate);
        this.sendMessage({
          type: "ice-candidate",
          candidate: event.candidate,
          streamId: streamId,
        });
      } else {
        console.log("✅ ICE候选收集完成");
      }
    };

    // 添加ICE gathering状态监听
    this.peerConnection.onicegatheringstatechange = () => {
      console.log("🧊 ICE收集状态:", this.peerConnection.iceGatheringState);

      if (this.peerConnection.iceGatheringState === "complete") {
        console.log("✅ ICE候选收集完成");

        // 检查是否有TURN候选
        const stats = this.peerConnection.getStats();
        stats.then((reports) => {
          let hasRelay = false;
          reports.forEach((report) => {
            if (
              report.type === "local-candidate" &&
              report.candidateType === "relay"
            ) {
              hasRelay = true;
            }
          });

          if (!hasRelay) {
            console.warn("⚠️ 没有发现TURN候选，TURN服务器可能无法连接");
          } else {
            console.log("✅ 检测到TURN候选，TURN服务器工作正常");
          }
        });

        // 添加连接状态检查
        setTimeout(() => {
          console.log("⏰ 5秒后检查连接状态:");
          console.log(
            "  - ICE连接状态:",
            this.peerConnection.iceConnectionState
          );
          console.log("  - 整体连接状态:", this.peerConnection.connectionState);
          console.log("  - 信令状态:", this.peerConnection.signalingState);

          if (this.peerConnection.iceConnectionState === "checking") {
            console.warn("⚠️ ICE连接检查超时，可能需要TURN服务器");
          }
        }, 5000);

        // 10秒后再次检查
        setTimeout(() => {
          if (
            this.peerConnection.iceConnectionState !== "connected" &&
            this.peerConnection.iceConnectionState !== "completed"
          ) {
            console.error(
              "❌ ICE连接失败，最终状态:",
              this.peerConnection.iceConnectionState
            );
            if (this.onError) {
              this.onError("P2P连接建立失败，可能需要TURN服务器或网络配置问题");
            }
          }
        }, 10000);
      }
    };

    console.log("请求加入直播间:", streamId);
    // 请求加入直播间
    this.sendMessage({
      type: "join-stream",
      streamId: streamId,
    });
  }

  async handleCreateOffer(message) {
    console.log("=== 收到create-offer请求 ===");
    console.log("请求详情:", message);
    console.log("PeerConnection状态:", this.peerConnection?.signalingState);
    console.log("本地流存在:", !!this.localStream);

    if (!this.peerConnection || !this.localStream) {
      console.error("PeerConnection或localStream不存在");
      return;
    }

    // 检查发送器状态
    const senders = this.peerConnection.getSenders();
    console.log("当前发送器数量:", senders.length);
    senders.forEach((sender, index) => {
      console.log(`发送器${index}:`, {
        track: sender.track?.kind,
        enabled: sender.track?.enabled,
        readyState: sender.track?.readyState,
      });
    });

    try {
      console.log("开始创建offer...");
      const offer = await this.peerConnection.createOffer();
      console.log("offer创建成功，类型:", offer.type);

      await this.peerConnection.setLocalDescription(offer);
      console.log("本地描述设置成功");

      this.sendMessage({
        type: "offer",
        offer: offer,
        streamId: message.streamId,
        viewerId: message.viewerId,
      });

      console.log("offer已发送到信令服务器，目标观众:", message.viewerId);
    } catch (error) {
      console.error("创建offer失败:", error);
      console.error("错误详情:", error.message);
    }
  }

  async handleOffer(message) {
    console.log("收到offer:", message);
    console.log("当前PeerConnection状态:", this.peerConnection?.signalingState);

    if (!this.peerConnection) {
      console.error("PeerConnection不存在");
      return;
    }

    // 检查信令状态
    if (this.peerConnection.signalingState !== "stable") {
      console.warn(
        "PeerConnection状态不是stable，当前状态:",
        this.peerConnection.signalingState
      );
      console.warn("尝试继续处理offer...");
    }

    try {
      await this.peerConnection.setRemoteDescription(message.offer);
      console.log("设置远程描述(offer)成功");

      // 处理暂存的ICE候选
      await this.processPendingCandidates();

      const answer = await this.peerConnection.createAnswer();
      await this.peerConnection.setLocalDescription(answer);

      this.sendMessage({
        type: "answer",
        answer: answer,
        streamId: message.streamId,
      });

      console.log("发送answer回复");
    } catch (error) {
      console.error("处理offer失败:", error);
      console.error("错误详情:", error.message);
    }
  }

  async handleAnswer(message) {
    console.log("收到answer:", message);
    console.log("当前PeerConnection状态:", this.peerConnection?.signalingState);

    if (!this.peerConnection) {
      console.error("PeerConnection不存在");
      return;
    }

    // 检查信令状态
    if (this.peerConnection.signalingState !== "have-local-offer") {
      console.warn(
        "PeerConnection状态不是have-local-offer，当前状态:",
        this.peerConnection.signalingState
      );
      console.warn("尝试继续设置远程描述...");
    }

    try {
      await this.peerConnection.setRemoteDescription(message.answer);
      console.log("设置远程描述(answer)成功");

      // 处理暂存的ICE候选
      await this.processPendingCandidates();
    } catch (error) {
      console.error("设置远程描述失败:", error);
      console.error("错误详情:", error.message);
    }
  }

  async handleIceCandidate(message) {
    const candidateStr = message.candidate.candidate;
    const candidateType = candidateStr.includes("typ host")
      ? "HOST"
      : candidateStr.includes("typ srflx")
      ? "SRFLX(STUN)"
      : candidateStr.includes("typ relay")
      ? "RELAY(TURN)"
      : "OTHER";

    console.log(`🔄 收到ICE候选 [${candidateType}]:`, candidateStr);
    console.log("当前PeerConnection状态:", this.peerConnection?.signalingState);

    if (!this.peerConnection) {
      console.error("PeerConnection不存在，无法添加ICE候选");
      return;
    }

    // 初始化候选队列
    if (!this.pendingCandidates) {
      this.pendingCandidates = [];
    }

    // ICE候选需要在有远程描述之后才能添加
    if (this.peerConnection.remoteDescription) {
      try {
        await this.peerConnection.addIceCandidate(message.candidate);
        console.log(`✅ ICE候选添加成功 [${candidateType}]`);
      } catch (error) {
        console.error(`❌ ICE候选添加失败 [${candidateType}]:`, error);
        console.error("错误详情:", error.message);
      }
    } else {
      console.warn(`⚠️ 远程描述未设置，暂存ICE候选 [${candidateType}]`);
      this.pendingCandidates.push(message.candidate);
    }
  }

  // 处理暂存的ICE候选
  async processPendingCandidates() {
    if (!this.pendingCandidates || this.pendingCandidates.length === 0) {
      return;
    }

    console.log(`📦 处理${this.pendingCandidates.length}个暂存的ICE候选`);

    for (const candidate of this.pendingCandidates) {
      try {
        await this.peerConnection.addIceCandidate(candidate);
        const candidateStr = candidate.candidate;
        const candidateType = candidateStr.includes("typ host")
          ? "HOST"
          : candidateStr.includes("typ srflx")
          ? "SRFLX(STUN)"
          : candidateStr.includes("typ relay")
          ? "RELAY(TURN)"
          : "OTHER";
        console.log(`✅ 暂存ICE候选添加成功 [${candidateType}]`);
      } catch (error) {
        console.error("❌ 暂存ICE候选添加失败:", error);
      }
    }

    this.pendingCandidates = [];
  }

  async updateStream(newStream) {
    if (!this.peerConnection) return;

    // 移除旧的轨道
    this.peerConnection.getSenders().forEach((sender) => {
      this.peerConnection.removeTrack(sender);
    });

    // 添加新的轨道
    newStream.getTracks().forEach((track) => {
      this.peerConnection.addTrack(track, newStream);
    });

    this.localStream = newStream;
  }

  stopStreaming() {
    if (this.peerConnection) {
      this.peerConnection.close();
      this.peerConnection = null;
    }

    if (this.streamId) {
      this.sendMessage({
        type: "stop-stream",
        streamId: this.streamId,
      });
    }

    this.localStream = null;
    this.streamId = null;
    this.pendingCandidates = [];
  }

  leaveStream() {
    if (this.peerConnection) {
      this.peerConnection.close();
      this.peerConnection = null;
    }

    if (this.streamId) {
      this.sendMessage({
        type: "leave-stream",
        streamId: this.streamId,
      });
    }

    this.remoteStream = null;
    this.streamId = null;
    this.pendingCandidates = [];
  }

  sendMessage(message) {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(message));
    } else {
      console.error("WebSocket 未连接");
    }
  }

  generateStreamId() {
    return "stream_" + Math.random().toString(36).substr(2, 9);
  }

  disconnect() {
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }

    if (this.peerConnection) {
      this.peerConnection.close();
      this.peerConnection = null;
    }

    this.isConnected = false;
  }
}
